﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace Lilium.ComponentModel
{
	/// <summary>
	/// Base class for the extensions with sole owner
	/// </summary>
	public abstract class BasicExtension<TOwner> : IExtension<TOwner>
	{
		#region IExtension<TOwner> Members

		public void Attach(TOwner owner)
		{
			if (owner == null) throw new ArgumentNullException("owner");

			if (Owner != null)
				throw new InvalidOperationException(Resources.SimleExtensionBase_ExtensionAlreadyAttached);

			Owner = owner;
			OnAttach();
		}

		public void Detach(TOwner owner)
		{
			if (owner == null) throw new ArgumentNullException("owner");
			if (!EqualityComparer<TOwner>.Default.Equals(Owner, owner))
				throw new InvalidOperationException(Resources.SimleExtensionBase_ExtensionAlreadyAttached);

			OnDetach();
			Owner = default(TOwner);
		}

		#endregion

		protected TOwner EnsureAttached()
		{
			if (Owner == null)
				throw new InvalidOperationException(Resources.SimleExtensionBase_ExtensionNotAttachedToOwner);
			return Owner;
		}

		protected abstract void OnAttach();

		protected abstract void OnDetach();
		
		#region protected TOwner Owner

		private TOwner m_Owner;

		protected TOwner Owner
		{
			[DebuggerNonUserCodeAttribute]
			get
			{
				return m_Owner;
			}
			private set
			{
				m_Owner = value;
			}
		}

		#endregion
	}
}